package com.example.myapp.chat;

import android.util.Log;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class ChatManager {

    public static final String HOST = "192.168.95.1";
    public static final int PORT = 9000;
    public static final int TIME_OUT = 0 * 1000;
    public static final int READ_TIME_MS = 1 * 50;

    private ChatMessage chatMessage;

    private Socket socket;

    private DataOutputStream out;

    private BufferedReader br;

    private static ChatManager instance = null;

    private BlockingQueue<String> msgQueue = new ArrayBlockingQueue<String>(100);

    public void setChatMessage(ChatMessage chatMessage) {
        this.chatMessage = chatMessage;
    }

    private ChatManager(){
    }

    public static ChatManager getInstance(){
        if(instance==null){
            synchronized (ChatManager.class){
                if(instance==null){
                    instance = new ChatManager();
                    instance.init();
                }
            }
        }

        return instance;
    }

    private void init(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    socket = new Socket(HOST, PORT);
                    socket.setKeepAlive(true);
                    socket.setSoTimeout(TIME_OUT);
                    out = new DataOutputStream(socket.getOutputStream());
                    br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                    new PutMsgThread().start();

                    MsgReceiveThread runnable = new MsgReceiveThread(chatMessage);
                    new Thread(runnable).start();
                } catch (IOException e) {
                    Log.d("log","exception:"+e.getMessage());
                    e.printStackTrace();
                }
            }
        }).start();
    }

    private String buildMsg(String userId, String msg) {
        return userId+"%"+msg+"\r\n";
    }

    public String getMsg(){
        try {
            return msgQueue.take();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "";
    }

    public void close(){
        try {
            out.close();

            if(socket!=null)
                socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public boolean isConnected(){
        if(socket==null)return false;
        if(out==null)return false;
        if(!socket.isConnected())return false;

        return true;
    }

    class PutMsgThread extends Thread{

        @Override
        public void run() {
            String data = null;
            while(true){
                if(!isConnected())
                    init();

                try {
                    if((data=br.readLine())!=null){
                        msgQueue.put(data);
                        System.out.println("msgQueue count num:"+msgQueue.size());
                    }
                    Thread.sleep(READ_TIME_MS);
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void sendMsg(final String userId, final String msg){
        new Thread(new Runnable() {

            @Override
            public void run() {
                if(!isConnected())
                    init();

                try {
                    String msg2 = buildMsg(userId, msg);
                    out.writeUTF(msg2);
                    out.flush();
                    Log.d("log","msg sendMsg out!"+msg2);
                    chatMessage.onSendSuccess();
                } catch (IOException e) {
                    Log.d("log","exception2:"+e.getMessage());
                    e.printStackTrace();
                    chatMessage.onSendFailure(e);
                }
            }
        }).start();
    }

}
